package com.baijiayun.live.ui.widget

import android.content.Context
import android.content.res.Configuration
import android.util.AttributeSet
import android.util.DisplayMetrics
import android.view.MotionEvent
import android.view.ViewGroup
import android.view.WindowManager
import androidx.constraintlayout.widget.ConstraintLayout
import com.baijiayun.live.ui.R
import kotlin.math.abs
import kotlin.math.max

/**
 * Created by pengwenjian on 2020/8/31
 * Describe:
 */
class DragLayout @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : ConstraintLayout(context, attrs, defStyleAttr) {
    private var screenWidth = 0
    private var screenHeight = 0
    private var lastX = 0
    private var lastY = 0
    private var dx = 0
    private var dy = 0
    private var statusBarHeight = 0
    private var useParentContainer = false
    // 实际移动layout阈值，偏移低于 50 则不 layout，避免点击时因为拖动无法触发子控件点击事件
    private val threshold = 50
    private var hasMove = false

    init {
        attrs?.run {
            val typedArray = context.obtainStyledAttributes(this, R.styleable.BJYDragLayout)
            useParentContainer = typedArray.getBoolean(R.styleable.BJYDragLayout_BJYUserParentContainer, false)
            typedArray.recycle()
        }
        initScreenParam(context)
    }

    override fun onConfigurationChanged(newConfig: Configuration?) {
        super.onConfigurationChanged(newConfig)
        initScreenParam(context)
    }

    private fun initScreenParam(context: Context) {
        val metric = DisplayMetrics()
        val wm = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
        wm.defaultDisplay.getMetrics(metric)
        screenWidth = metric.widthPixels
        screenHeight = metric.heightPixels
        val resourceId = resources.getIdentifier("status_bar_height", "dimen", "android")
        if (resourceId > 0) {
            //根据资源ID获取响应的尺寸值
            statusBarHeight = resources.getDimensionPixelSize(resourceId)
        }
        if (context.resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT) {
            screenHeight -= statusBarHeight
        }
    }

    override fun onInterceptTouchEvent(event: MotionEvent): Boolean {
        when (event.action) {
            MotionEvent.ACTION_DOWN -> {
                hasMove = false
                lastX = event.rawX.toInt()
                lastY = event.rawY.toInt()
                if (useParentContainer) {
                    if (parent is ViewGroup) {
                        val parent = parent as ViewGroup
                        screenWidth = parent.measuredWidth
                        screenHeight = parent.measuredHeight
                    }
                }
            }
            MotionEvent.ACTION_MOVE -> {
                // region 计算边界
                dx = event.rawX.toInt() - lastX
                dy = event.rawY.toInt() - lastY
                var nLeft: Int = left + dx
                var nTop: Int = top + dy
                var nRight: Int = right + dx
                var nBottom: Int = bottom + dy
                if (nLeft < 0) {
                    nLeft = 0
                    nRight = nLeft + width
                }
                if (nRight > screenWidth) {
                    nRight = screenWidth
                    nLeft = screenWidth - width
                }
                if (nTop < 0) {
                    nTop = 0
                    nBottom = nTop + height
                }
                if (nBottom > screenHeight) {
                    nBottom = screenHeight
                    nTop = screenHeight - height
                }
                // endregion
                if (checkNeedLayout(left, nLeft, top, nTop)) {
                    layout(nLeft, nTop, nRight, nBottom)
                    if (layoutParams is MarginLayoutParams) {
                        val params = layoutParams as MarginLayoutParams
                        params.leftMargin = nLeft
                        params.topMargin = nTop
                        params.rightMargin = screenWidth - nRight
                        params.bottomMargin = screenHeight - nBottom
                    }
                    lastX = event.rawX.toInt()
                    lastY = event.rawY.toInt()
                    hasMove = true
                }
            }
            //作用是屏蔽点击事件，直接返回true则子view点击不生效
            MotionEvent.ACTION_UP -> return hasMove
        }
        return super.onInterceptTouchEvent(event)
    }

    private fun checkNeedLayout(left: Int, nLeft: Int, top: Int, nTop: Int): Boolean = (max(abs(left - nLeft), abs(top - nTop)) > threshold) || hasMove
}